from django.db import transaction
from django.db.models import Q
from django.http import JsonResponse
from django.shortcuts import render
from django_redis import get_redis_connection
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import jwt_decode_handler

from TenSq.settings.dev import logger
from apps.answers.serializer.questions import QuestionsPostSerializer, QuestionModelSerializerForCreate, \
    QuestionsSerializer, QuestionModelSerializerForList

from apps.answers.models import Label, Question, Reply
from apps.answers.serializer.labels import LabelsSerializer, LabelsDetailSerializer, LabelFullSerializer

# Create your views here.


# 标签列表
from apps.answers.serializer.reply import ReplySerializerForCreate
from apps.users.models import User


class LabelsModelView(ModelViewSet):
    serializer_class = LabelsSerializer
    queryset = Label.objects.all()

    def retrieve(self, request, *args, **kwargs):
        label = self.get_object()
        serializer = LabelsDetailSerializer(label)
        return Response(serializer.data)



    # 用户关注的标签列表
    @action(methods=['get'], detail=False)
    def users(self, request):
        try:
            user = self.request.user
        except Exception as e:
            user = None
        # 用户认证
        if user is not None and user.is_authenticated:
            labels = user.labels.all()
            serializer = LabelsSerializer(labels, many=True)
            return Response(serializer.data)
        else:
            return Response([])

    # 关注标签
    @action(methods=['put'], detail=True)
    def focusin(self, request, pk):
        token = request.META.get('HTTP_AUTHORIZATION')[4:]
        token_user = jwt_decode_handler(token)
        user_id = token_user['user_id']
        user = User.objects.get(id=user_id)
        label = Label.objects.get(id=pk)
        # 添加用户的标签
        label.users.add(user)
        return Response({'message': '已关注', 'success': True})

    # 取消关注标签
    @action(methods=['put'], detail=True)
    def focusout(self, request, pk):
        token = request.META.get('HTTP_AUTHORIZATION')[4:]
        token_user = jwt_decode_handler(token)
        user_id = token_user['user_id']
        user = User.objects.get(id=user_id)
        label = Label.objects.get(id=pk)
        # 移除用户的标签
        label.users.remove(user)
        return Response({'message': '取消关注', 'success': True})

    # 获取标签,隐藏任务, labels/full
    @action(methods=['get'], detail=False)
    def full(self, request):
        labels = Label.objects.all()
        serializer = LabelFullSerializer(labels, many=True)
        return Response(serializer.data)


class QuestionViewSet(ModelViewSet):
    queryset = Question.objects.all()

    # 最新回答的问题
    @action(methods=['get'], detail=True, url_path="label/new")
    def new(self, request, pk):
        try:
            # id=-1时,为全部标签
            if pk == '-1':
                # 根据回复时间倒序
                questions = Question.objects.filter(reply__gt=0).order_by('-replytime')
                # 没有回答评论,先不设置过滤条件
                # questions = Question.objects.filter().order_by('-replytime')
            else:
                label = Label.objects.get(id=pk)
                questions = label.questions.filter(reply__gt=0).order_by('-replytime')
        except Exception as e:
            logger.error(e)
        else:
            serializer = QuestionsPostSerializer(questions, many=True)
            return Response(serializer.data)

    # 热门回答的问题
    @action(methods=['get'], detail=True, url_path="label/hot")
    def hot(self, request, pk):
        try:
            if pk == '-1':
                # 根据回复数量倒序
                questions = Question.objects.filter(reply__gt=0).order_by('-reply')
                # questions = Question.objects.filter().order_by('-reply')
            else:
                label = Label.objects.get(id=pk)
                questions = label.questions.filter(reply__gt=0).order_by('-reply')
        except Exception as e:
            logger.error(e)
        else:
            serializer = QuestionsPostSerializer(questions, many=True)
            return Response(serializer.data)

    # 等待回答的问题
    @action(methods=['get'], detail=True, url_path="label/wait")
    def wait(self, request, pk):
        try:
            if pk == '-1':
                # 根据创建时间倒序
                questions = Question.objects.filter(reply=0).order_by('-createtime')
                # questions = Question.objects.filter().order_by('-createtime')
            else:
                label = Label.objects.get(id=pk)
                questions = label.questions.filter(reply=0).order_by('-createtime')
        except Exception as e:
            logger.error(e)
        else:
            serializer = QuestionsPostSerializer(questions, many=True)
            return Response(serializer.data)

    # 发布问题
    def create(self, request, *args, **kwargs):
        try:
            user = request.user
        except Exception as e:
            logger.error(e)
            user = None
        if not user or not user.is_authenticated:
            return Response({'success': False, 'message': '未登录'}, status=400)
        data = request.data
        data["user"] = user.id
        serializer = QuestionModelSerializerForCreate(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({'success': True, 'message': '发布成功'})

    # 问题详情
    def retrieve(self, request, *args, **kwargs):
        question_id = self.kwargs['pk']
        question = Question.objects.get(id=question_id)
        # 访客+1
        question.visits = question.visits + 1
        question.save()
        serializer = QuestionsSerializer(question)
        return JsonResponse(serializer.data)

    # 问题有用
    @action(methods=['put'], detail=True)
    def useful(self, request, pk=None):
        token = request.META.get('HTTP_AUTHORIZATION')[4:]
        token_user = jwt_decode_handler(token)
        user_id = token_user['user_id']
        reply = Reply.objects.filter(problem_id=pk).filter(user_id=user_id).filter(type=3). \
            filter(Q(useful_count__gt=0) | (Q(unuseful_count__gt=0)))
        if reply.exists():
            return Response({'message': '请不要重复操作', 'success': False})
        else:
            with transaction.atomic():
                save_id = transaction.savepoint()
                question = Question.objects.get(id=pk)
                question.useful_count = question.useful_count + 1
                question.save()
                reply = Reply.objects.create(
                    problem_id=pk,
                    user_id=user_id,
                    useful_count=1,
                    type=3
                )
                transaction.savepoint_commit(save_id)

            return Response({'message': '操作成功', 'success': True})

    # 问题没用
    @action(methods=['put'], detail=True)
    def unuseful(self, request, pk=None):
        token = request.META.get('HTTP_AUTHORIZATION')[4:]
        token_user = jwt_decode_handler(token)
        user_id = token_user['user_id']
        reply = Reply.objects.filter(problem_id=pk).filter(user_id=user_id).filter(type=3). \
            filter(Q(useful_count__gt=0) | (Q(unuseful_count__gt=0)))
        if reply.exists():
            return Response({'message': '请不要重复操作', 'success': False})
        else:
            with transaction.atomic():
                save_id = transaction.savepoint()
                question = Question.objects.get(id=pk)
                question.unuseful_count = question.unuseful_count + 1
                question.save()
                reply = Reply.objects.create(
                    problem_id=pk,
                    user_id=user_id,
                    unuseful_count=1,
                    type=3
                )
                transaction.savepoint_commit(save_id)
            return Response({'message': '操作成功', 'success': True})


# 回答问题
class ReplyViewSet(ModelViewSet):
    queryset = Reply.objects.all()

    # 发布回答
    def create(self, request, *args, **kwargs):
        try:
            user = request.user
        except Exception as e:
            return Response({'success': False, 'message': '未登录'}, status=400)
        if user.is_authenticated:
            data = request.data
            data["user"] = user.id
            serializer = ReplySerializerForCreate(data=data)
            serializer.is_valid(raise_exception=True)
            reply = serializer.save()
            problem = reply.problem
            # 如果是回答,则更新对应的数据
            if data.get('type') == 2:
                problem.reply += 1
                problem.replyname = reply.user.username
                problem.replytime = reply.createtime
                problem.save()
            return Response({'success': True, 'message': '发布成功'})
        else:
            return Response({'success': False, 'message': '未登录'}, status=400)

    # 回答有用
    @action(methods=['put'], detail=True)
    def useful(self, request, pk=None):
        token = request.META.get('HTTP_AUTHORIZATION')[4:]
        token_user = jwt_decode_handler(token)
        user_id = token_user['user_id']
        reply = Reply.objects.get(id=pk)
        question_id = reply.problem_id
        reply = Reply.objects.filter(parent_id=pk).filter(user_id=user_id).filter(type=4). \
            filter(Q(useful_count__gt=0) | (Q(unuseful_count__gt=0)))
        if reply.exists():
            return Response({'message': '请不要重复操作', 'success': False})
        else:
            with transaction.atomic():
                save_id = transaction.savepoint()
                reply = Reply.objects.get(id=pk)
                reply.useful_count = reply.useful_count + 1
                reply.save()
                reply = Reply.objects.create(
                    parent_id=pk,
                    user_id=user_id,
                    useful_count=1,
                    type=4,
                    problem_id=question_id,
                )

                transaction.savepoint_commit(save_id)

            return Response({'message': '操作成功', 'success': True})

    # 回答没用
    @action(methods=['put'], detail=True)
    def unuseful(self, request, pk=None):
        token = request.META.get('HTTP_AUTHORIZATION')[4:]
        token_user = jwt_decode_handler(token)
        user_id = token_user['user_id']
        reply = Reply.objects.get(id=pk)
        question_id = reply.problem_id
        reply = Reply.objects.filter(parent_id=pk).filter(user_id=user_id).filter(type=4). \
            filter(Q(useful_count__gt=0) | (Q(unuseful_count__gt=0)))
        if reply.exists():
            return Response({'message': '请不要重复操作', 'success': False})
        else:
            with transaction.atomic():
                save_id = transaction.savepoint()
                reply = Reply.objects.get(id=pk)
                reply.unuseful_count = reply.unuseful_count + 1
                reply.save()
                reply = Reply.objects.create(
                    parent_id=pk,
                    user_id=user_id,
                    unuseful_count=1,
                    type=4,
                    problem_id=question_id,
                )
                transaction.savepoint_commit(save_id)

            return Response({'message': '操作成功', 'success': True})
